module Test where

import System.CPUTime
import System.IO


pushntimes p q 0 = q
pushntimes p q n = pushntimes p (p n q) (n-1)

removentimes r q 0 = q
removentimes r q n = removentimes r (r q) (n-1)

rInt :: String -> Int
rInt = read

runTest p r q [] = q
runTest p r q (c:args) = if c == "push"
                         then runTest p r (pushntimes p q (rInt (head args))) (tail args)
                         else runTest p r (removentimes r q (rInt (head args))) (tail args)

--multiTest p r q m 0 i = print "Done"
multiTest p r q m n i = multiTest' p r q m n i 0
multiTest' p r q m n i j = if j > n
                           then print "Done"
                           else do start <- getCPUTime
                                   writeFile "out.dat" (show (m (runTest 
                                                                 p
                                                                 r
                                                                 q
                                                                 ["push", (show j), "remo", (show j)])))
                                   end <- getCPUTime
                                   appendFile "result.dat" ((show j) ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                   multiTest' p r q m n i (j+i)

removeTest r q m n i j = if j > (n-1)
                         then print "Done"
                         else do start <- getCPUTime
                                 writeFile "out.dat" (show (m (removentimes r q i)))
                                 end <- getCPUTime
                                 appendFile "result.dat" ((show j) ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                 removeTest r (removentimes r q i) m n i (j+i)


pushTest p p' q m n i j = if j > (n-1)
                          then print "Done"
                          else do start <- getCPUTime
                                  appendFile "out.dat" (show (p' q))
                                  end <- getCPUTime
                                  appendFile "result.dat" ((show j) ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                  pushTest p p' (pushntimes p q i) m n i (j+i)

pushremovenTest p r q m n i j = if j > (n-1)
                                then print "Done"
                                else do let i' = ((j+1)*i)
                                        start <- getCPUTime
                                        writeFile "out.dat" (show (m (removentimes r (pushntimes p q i') i')))
                                        end <- getCPUTime
                                        appendFile "result.dat" ((show i') ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                        pushremovenTest p r q m n i (j+1)


repeatRemove r p q 0 = writeFile "out.dat" (show (p q))
repeatRemove r p q n = do writeFile "out.dat" (show (p q))
                          repeatRemove r p q (n-1)

rrTest p r p' q m n i j = if j > (n-1)
                          then print "Done"
                          else do let i' = ((j+1)*i)
                                  start <- getCPUTime
                                  writeFile "out.dat" (show (p' q))
                                  repeatRemove r p' q 1
                                  end <- getCPUTime
                                  appendFile "result.dat" ((show i') ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                  rrTest p r p' (pushntimes p q i) m n i (j+1)


repeatTest p r p' e q m n i j = if j > (n-1)
                                then print "Done"
                                else do start <- getCPUTime
                                        writeFile "out.dat" ((show (p' q)) ++ "\n")
                                        end <- getCPUTime
                                        appendFile "result.dat" ((show j) ++ " " ++ (show ((fromIntegral (end-start)) / (10^12))) ++ "\n")
                                        repeatTest p r p' e (pushntimes p e ((j+1)*i)) m n i (j+1)


{-- ~~~~~~~~~~~~ |: push 2, pop 1 :| test: ~~~~~~~~~~~~ -}


ppTest p r q m n = ppTest' p r q m n 0
ppTest' p r q m n j = if j > n
                      then print "Done"
                      else do start <- getCPUTime
                              writeFile "out.dat" (show (m (r (p j (p j q)))))
                              end <- getCPUTime
                              let diff = ((fromIntegral (end-start)) / (10^12))
                              if diff > 0.01
                               then appendFile "result.dat" ((show j) ++ " " ++ (show diff) ++ "\n")
                               else appendFile "result.dat" ""
                              ppTest' p r (r (p j (p j q))) m n (j+1)
                                      

